package quarto.controller;

/**
 * Dit is het communicatie-protocol dat gebruikt wordt bij het spelen van het
 * spel Quarto.
 *
 * Het spel Quarto wordt gespeeld op een bord van 16 (4x4) vakjes. De vakjes zijn
 * genummerd van 0 t/m 15 met linksboven gerepresenteerd door 0 en rechtsonder
 * gerepresenteerd door 15.
 * Naast het bord zijn er voor Quarto ook 16 unieke stukken nodig. De stukken
 * hebben allemaal 4 kenmerken: de kleur, het formaat, de vorm en de openheid.
 *
 * In dit protocol staat beschreven welke commando's met welke parameters
 * uitgewisseld kunnen worden via de socket-verbinding tussen de clients
 * en de servers.
 *
 * Voor vragen of opmerkingen: info@frnk.net
 *
 * @author Frank Borgonjen & Peter-Paul van Gemerden
 * @version 1.4 - 14/03/2008
 */
public interface Protocol
{
	/**
	 * Om de commando's en parameters te kunnen onderscheiden is het van belang
	 * dat er een delimiter gebruikt wordt. 
	 * NB: In de commando's zal deze delimiter dus niet voor mogen komen.
	 *     In dit document wordt niet verwezen naar DELIM, maar zal gewoon het
	 *     karakter "|" gebruikt worden.
	 */
	public static final String DELIM         = "|";
	
	/** 
	* Onderstaande String kan gebruikt worden zodra je bovenstaande 
	* delimiter gebruikt voor een Scanner.
	*/
	public static final String SCANNER_DELIM = "\\|";
	
	/**
	 * Omdat er in een aantal parameters boolean waardes meegestuurd worden, zijn
	 * hier de representaties van true en false gedefinieerd.
	 */
	public static final String TRUE  = "true";
	public static final String FALSE = "false";
	
	/**
	 * Om mee te kunnen doen aan een spel, moet de client het volgende commando 
	 * sturen naar de server:
	 *
	 * JOIN|[kanChat]|[naam]
	 *
	 * [kanChat]    Geeft aan of de client de chat functionaliteit geimplementeerd heeft. 
	 *              Het bevat een van de boolean representaties die in dit document 
	 *              beschreven staan.
	 *
	 * [naam]       Is de gebruikersnaam die de client wil gebruiken. 
	 *              Zodra de server constateert dat de naam al in gebruik is, zal er een
	 *              random getal achter geplakt worden.
	 */
	public static final String JOIN 	= "join";
	
	
	/**
	 * Zodra er twee clients met de server verbonden zijn die allebei nog geen spel
	 * spelen, zal er een spel gestart worden. De clients worden op de hoogte gebracht
	 * door de server met het volgende commando:
	 *
	 * START|[naamJezelf]|[naamAnder]|[metChat]
	 *
	 * [naamJezelf] Is de gebruikersnaam die de jouw client representeerd tijdens het spel.
	 * [naamAnder]  Is de gebruikersnaam die de tegenstander representeerd tijdens het spel.
	 * [metChat]    Geeft aan of beide gebruikers de chatfunctionaliteit hebben geimplementeerd.
	 *
	 * NB: De namen worden meegestuurd omdat de server de mogelijkheid heeft om een 
	 * gebruikersnaam te veranderen indien deze niet uniek is.
	 */
	public static final String START = "start";
	
	
	/**
	 * Met het volgende commando geeft de server aan de client aan dat hij aan de beurt is,
	 * en met welk stuk hij moet spelen.
	 * 
	 * MAKEMOVE|[stuk]
	 *
	 * [stuk]       Is het stuk die de client moet gebruiken om zijn volgende zet te doen.
	 *              Aangezien stuk vier boolse-eigenschappen heeft, is dit opgebouwd uit vier 
	 *              met delimiter gescheiden waardes namelijk: isDonker|isGroot|isRond|isOpen
	 *
	 * NB: Het eerste stuk dat uitgedeeld wordt door de server is het lichte grote ronde 
	 * dichte stuk.
	 */
	public static final String MAKEMOVE = "makemove";
	
	/**
	 * Zodra een client bepaald heeft waar hij zijn stuk neer zet en een stuk gekozen heeft
	 * voor de tegenstander wordt een van de volgende commando's gestuurd naar de server:
	 *
	 * MOVE|[locatie]|[stuk]
	 * MOVE|[locatie]
	 *
	 * [locatie]    Is het getal wat het vakje op het bord representeerd waar de client
	 *              zijn stuk, die hij daarvoor gekregen heeft, neerzet.
	 *
	 * [stuk]       Is het stuk wat de client gekozen heeft voor zijn tegenstander. Indien
	 *              [stuk] niet gedefinieerd is, betekend het dat er geen stukken meer 
	 *              over zijn.
	 *              [stuk] is net als bij MAKEMOVE opgebouwd uit vier booleans.
	 */
	public static final String MOVE = "move";
	
	/**
	 * Nadat de server het commando MOVE ontvangen heeft, checkt de server of de zet
	 * toegestaan is. Indien de zet is toegestaan, zal de server naar beide clients een 
	 * van de volgende commando's sturen:
	 *
	 * MOVED|[locatie]|[stuk]
	 *
	 * [locatie]    Is het getal wat het vakje op het bord representeerd waar het huidige 
	 *              stuk op geplaatst moet worden. 
	 *
	 * [stuk]       Is het stuk dat geplaatst moet worden. (deze moet dan natuurlijk wel 
	 *              overeenkomen met wat er door de server via MAKEMOVE gestuurd is)
	 *              [stuk] is net als bij MAKEMOVE opgebouwd uit vier booleans.
	 *
	 * NB: Indien de zet NIET toegestaan is, zal de client die aan de beurt is, nogmaals 
	 * gevraagd worden om een zet te doen.
	 */
	public static final String MOVED = "moved";
	
	/**
	 * Zodra het spel (op welke manier dan ook) afgelopen is zal de server een van de 
	 * volgende commando's versturen aan beide clients:
	 * 
	 * GAMEOVER|[naamWinnaar]
	 * GAMEOVER
	 *
	 * [naamWinnaar]    Is de naam van de client die gewonnen heeft. Indien dit leeg is,
	 *                  betekend het dat het een remise is.
	 *
	 * NB: Zodra de verbinding met een van de clients verbroken is zal de server dit commando
	 * sturen naar de client die over is. Deze client is de winnaar.
	 */
	public static final String GAMEOVER = "gameover";
	
	/**
	 * Indien beide clients en de server beschikken over chatfunctionaliteit kunnen er
	 * berichten verstuurd worden. De clients sturen hun bericht naar de server die op zijn
	 * beurt het bericht voorziet van een naam van de afzender en doorstuurt naar beide 
	 * clients. De server gebruikt hiervoor hetzelfde commando. Dit is dus een commando
	 * dat van client naar server en vice versa gebruikt kan worden. 
	 *
	 * MSG|[tekst]
	 *
	 * [tekst]      Het bericht dat wel of niet voorzien is van de naam van de afzender.
	 *
	 */
	public static final String MSG = "msg";
	
	/**
	 * Als een client het spel beeindigd zal het volgende commando verstuurd worden naar
	 * de server:
	 *
	 * QUIT
	 * 
	 * NB: De server stuurt na het ontvangen van dit commando een bericht (via MSG) met de 
	 * mededeling en een GAMEOVER naar de andere client zodat die op de hoogte is. Die 
	 * client is in dit geval de winnaar.
	 */
	public static final String QUIT = "quit";
	
	
	
	
	// ------ EXTRA CHALLENGE-FUNCTIONALITEIT ------- //
	// Voor vragen of opmerkingen: info@ppvg.nl
	
	/**
	* Als de client ondersteuning biedt voor de "Challenge"-functie, stuurt hij vóór het
	* commando JOIN te sturen eerst het commando:
	* 
	* CHALLENGEABLE|[challengeable]
	* 
	* [challengeable]	- Indien true ondersteunt de client de Challenge-functionaliteit en
	* 					wil deze gebruiken.
	* 					- Indien false wil de client géén challenge-functie gebruiken (ook
	* 					niet via chat), ongeacht of deze is geïmplementeerd.
	* 					- Indien deze parameter wordt weggelaten neemt de server aan dat de
	* 					client de Challenge-functie niet heeft geïmplementeerd, maar kan
	* 					de server de client eventueel aanbieden deze functie via de chat
	* 					te bieden.
	*/
	public static final String CHALLENGEABLE = "challengeable";
	
	/**
	* De server kan een client die het Challenge-protocol ondersteunt een lijst van users
	* sturen:
	* 
	* USERLIST|[user]|[user]|[user]|[user]|[user]|[et cetera]
	* 
	* In principe wordt dit commando gestuurt zodra een verandering plaats vindt in de
	* samen stelling van de lijst clients. Een client kan (en hoeft) de lijst niet aan
	*  te vragen. Het maakt dan ook niet uit wanneer de eerste USERLIST naar de client
	*  wordt gestuurd.
	*/
	public static final String USERLIST = "userlist";
	
	/**
	* Als een client een bepaalde user uit wil dagen voor een potje Quarto, stuurt hij
	* naar de server:
	* 
	* CHALLENGE|[username]
	* 
	* [username]	De naam van de gebruiker die uitgedaagd wordt.
	* 
	* De server laat vervolgens op een vergelijkbare wijze de uitgedaagde client weten
	* dat (en door wie) hij/zij uitgedaagd is:
	* 
	* CHALLENGE|[username]
	* 
	* [username]	De naam van de gebruiker die de uitdaging gestuurd heeft.
	* 
	* NB: Een client kan altijd maar één iemand tegelijk uitdagen en door één iemand
	* tegelijk uitgedaagd worden. Bovendien kan een client niet tegelijk uitdagen
	* en uitgedaagd worden. De server moet dus een soort status bijhouden; een
	* boolean die beschrijft of een client op het moment aan het uidagen is of
	* uitgedaagd wordt.  Als een client een tweede client uitdaagd terwijl die
	* tweede client bezig is met een potje, kan de server wachten met het versturen
	* van de uitdaging totdat het potje is afgelopen, of de uitdaging automatisch
	* afwijzen.
	*/
	public static final String CHALLENGE = "challenge";
	
	/**
	* Een uitgedaagde client kan de uitdaging als volgt accepteren:
	* 
	* ACCEPTCHALLENGE|[accept]
	* 
	* [accept]		true als de client de uitdaging accepteert. Anders false.
	* 
	* De server laat vervolgens de uitdager weten of zijn/haar uitdaging is geaccepteerd
	* met:
	* 
	* ACCEPTCHALLENGE|[accept]
	* 
	* [accept]		true als de uitdaging is geaccepteerd. Anders false.
	*/
	public static final String ACCEPTCHALLENGE = "acceptchallenge";
	
	/**
	* Een client die een uitdaging heeft verstuurd kan deze terugnemen met:
	* 
	* CANCELCHALLENGE
	* 
	* De server stuurt vervolgens naar de uitgedaagde client:
	* 
	* CANCELCHALLENGE
	* 
	* NB: In het onwaarschijnlijke geval dat een CANCELCHALLENGE van de server naar
	* de (uitgedaagde) client pas aankomt nadat de client de uitdaging heeft
	* geaccepteerd, wordt het accepteren genegeerd en wordt geen spel gestart.
	*/
	public static final String CANCELCHALLENGE = "cancelchallenge";
	
	/**
	* Een server die ondersteuning biedt voor de "Score"-functionaliteit stuurt na
	* elk potje dat een bepaalde client heeft gespeeld:
	* 
	* SCORE|[gewonnen]|[verloren]|[gelijkspel]
	* 
	* [gewonnen]	Het aantal keren dat de client een spel heeft gewonnen
	* [verloren]	Het aantal keren dat de client een spel heeft verloren
	* [gelijkspel]	Het aantal spellen waarin de client gelijkspel heeft meegemaakt.
	* 
	* NB: Alle drie de parameters worden verstuurd als integers.
	*/
	public static final String SCORE = "score";
	
}